package com.ssy.lingxi.member.merchant.serviceimpl.web;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.constant.member.MemberStatusEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.bo.ChannelAuthBO;
import com.ssy.lingxi.member.merchant.model.constant.MemberUserAuthTypeEnum;
import com.ssy.lingxi.member.merchant.model.constant.MemberValidateStatusEnum;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.UserPageVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.*;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.*;
import com.ssy.lingxi.member.merchant.model.vo.manage.request.MemberManagePageByNameVO;
import com.ssy.lingxi.member.merchant.repository.*;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberCacheService;
import com.ssy.lingxi.member.merchant.service.web.IMemberAbilitySalesService;
import com.ssy.lingxi.member.merchant.utils.MemberOrganizationUtil;
import com.ssy.lingxi.member.merchant.utils.NumberUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 渠道能力 - 业务员管理服务接口实现类
 *
 * @author 万宁
 * @version 2.0.0
 * @date 2021-04-14
 */
@Service
public class MemberAbilitySalesServiceImpl implements IMemberAbilitySalesService {
    @Resource
    private MemberRepository memberRepository;

    @Resource
    private MemberUserRepository memberUserRepository;

    @Resource
    private MemberUserAuthRepository memberUserAuthRepository;

    @Resource
    private MemberUserChannelRepository memberUserChannelRepository;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private IBaseMemberCacheService memberCacheService;

    @Resource
    private JPAQueryFactory jpaQueryFactory;

    /**
     * 分页查询已经绑定渠道的业务员列表
     *
     * @param headers HttpHeader信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberSalesPageQueryVO>> pageMemberSales(HttpHeaders headers, MemberSalesPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberDO memberDO = memberRepository.findById(loginUser.getMemberId()).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        List<MemberOrganizationDO> orgList = new ArrayList<>(memberDO.getOrgs());

        Pageable pageable = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("id").ascending());

        Specification<MemberUserDO> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            //注意这里的写法，会转换为查询member_id
            list.add(criteriaBuilder.equal(root.get("member").as(MemberDO.class), loginUser.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("isSales").as(Integer.class), EnableDisableStatus.ENABLE.getCode()));
            list.add(criteriaBuilder.equal(root.get("typeEnum").as(Integer.class), MemberUserAuthTypeEnum.NORMAL.getCode()));

            if (StringUtils.hasLength(pageVO.getAccount())) {
                list.add(criteriaBuilder.like(root.get("account").as(String.class), "%" + pageVO.getAccount().trim() + "%"));
            }

            if (StringUtils.hasLength(pageVO.getName())) {
                list.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + pageVO.getName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<MemberUserDO> pageList = memberUserRepository.findAll(specification, pageable);

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(memberUserDO -> {
            MemberSalesPageQueryVO queryVO = new MemberSalesPageQueryVO();
            queryVO.setUserId(memberUserDO.getId());
            queryVO.setAccount(memberUserDO.getAccount());
            queryVO.setName(memberUserDO.getName());
            queryVO.setCountryCode(memberUserDO.getCountryCode());
            queryVO.setPhone(memberUserDO.getPhone());
            queryVO.setMemberRoleName(memberUserDO.getRoles().stream().map(MemberRoleDO::getRoleName).collect(Collectors.joining(",")));
            queryVO.setJobTitle(StringUtils.hasLength(memberUserDO.getJobTitle()) ? memberUserDO.getJobTitle() : "");
            queryVO.setOrgName(MemberOrganizationUtil.joinTitleToString(memberUserDO.getOrg() == null ? 0L : memberUserDO.getOrg().getId(), orgList));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 分页查询业务员列表
     *
     * @param headers HttpHeader信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberSalesSelectQueryVO>> pageSelectMemberSales(HttpHeaders headers, UserPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberDO memberDO = memberRepository.findById(loginUser.getMemberId()).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        List<MemberOrganizationDO> orgList = new ArrayList<>(memberDO.getOrgs());

        Pageable pageable = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("id").ascending());
        Specification<MemberUserDO> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            //注意这里的用法，Jpa会转换为Id查询
            list.add(criteriaBuilder.equal(root.get("member").as(MemberDO.class), loginUser.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), EnableDisableStatus.ENABLE.getCode()));
            list.add(criteriaBuilder.equal(root.get("typeEnum").as(Integer.class), MemberUserAuthTypeEnum.NORMAL.getCode()));
            //选取还不是业务员的
            list.add(criteriaBuilder.equal(root.get("isSales").as(Integer.class), EnableDisableStatus.DISABLE.getCode()));

            if (StringUtils.hasLength(pageVO.getName())) {
                list.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + pageVO.getName().trim() + "%"));
            }

            if (StringUtils.hasLength(pageVO.getOrgName())) {
                Join<Object, Object> orgJoin = root.join("org", JoinType.LEFT);
                list.add(criteriaBuilder.like(orgJoin.get("title").as(String.class), "%" + pageVO.getOrgName().trim() + "%"));
            }

            if (StringUtils.hasLength(pageVO.getJobTitle())) {
                list.add(criteriaBuilder.like(root.get("jobTitle").as(String.class), "%" + pageVO.getJobTitle().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<MemberUserDO> pageList = memberUserRepository.findAll(specification, pageable);

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(memberUserDO -> {
            MemberSalesSelectQueryVO queryVO = new MemberSalesSelectQueryVO();
            queryVO.setUserId(memberUserDO.getId());
            queryVO.setPhone(memberUserDO.getPhone());
            queryVO.setName(memberUserDO.getName());
            queryVO.setJobTitle(StringUtils.hasLength(memberUserDO.getJobTitle()) ? memberUserDO.getJobTitle() : "");
            queryVO.setOrgName(MemberOrganizationUtil.joinTitleToString(memberUserDO.getOrg() == null ? 0L : memberUserDO.getOrg().getId(), orgList));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 新增业务员
     *
     * @param headers HttpHeader信息
     * @param idVO    接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberSalesGetVO> addMemberSales(HttpHeaders headers, MemberUserIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberUserDO userDO = memberUserRepository.findById(idVO.getUserId()).orElse(null);
        if (userDO == null || userDO.getMember() == null || !userDO.getMember().getId().equals(loginUser.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        if (NumberUtil.notNullOrZero(userDO.getIsSales()) && userDO.getIsSales().equals(EnableDisableStatus.ENABLE.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_IS_ALREADY_SALES);
        }

        userDO.setIsSales(EnableDisableStatus.ENABLE.getCode());
        userDO.getUserAuth().setChannelAuth(new ArrayList<>());
        memberUserRepository.saveAndFlush(userDO);

        List<MemberOrganizationDO> orgList = new ArrayList<>(userDO.getMember().getOrgs());

        MemberSalesGetVO getVO = new MemberSalesGetVO();
        getVO.setUserId(userDO.getId());
        getVO.setName(userDO.getName());
        getVO.setMemberRoleName(userDO.getRoles().stream().map(MemberRoleDO::getRoleName).collect(Collectors.joining(",")));
        getVO.setOrgName(MemberOrganizationUtil.joinTitleToString(userDO.getOrg() == null ? 0L : userDO.getOrg().getId(), orgList));
        getVO.setCountryCode(StringUtils.hasLength(userDO.getCountryCode()) ? userDO.getCountryCode() : "");
        getVO.setPhone(userDO.getPhone());
        getVO.setJobTitle(StringUtils.hasLength(userDO.getJobTitle()) ? userDO.getJobTitle() : "");

        return Wrapper.success(getVO);
    }

    /**
     * 查询业务员基本信息
     *
     * @param headers HttpHeader信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberSalesGetVO> getMemberSales(HttpHeaders headers, MemberUserIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberUserDO userDO = memberUserRepository.findById(idVO.getUserId()).orElse(null);
        if (userDO == null || userDO.getMember() == null || !userDO.getMember().getId().equals(loginUser.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        if (userDO.getIsSales() == null || userDO.getIsSales().equals(EnableDisableStatus.DISABLE.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_IS_NOT_SALES);
        }

        List<MemberOrganizationDO> orgList = new ArrayList<>(userDO.getMember().getOrgs());

        MemberSalesGetVO getVO = new MemberSalesGetVO();
        getVO.setUserId(userDO.getId());
        getVO.setName(userDO.getName());
        getVO.setMemberRoleName(userDO.getRoles().stream().map(MemberRoleDO::getRoleName).collect(Collectors.joining(",")));
        getVO.setOrgName(MemberOrganizationUtil.joinTitleToString(userDO.getOrg() == null ? 0L : userDO.getOrg().getId(), orgList));
        getVO.setCountryCode(StringUtils.hasLength(userDO.getCountryCode()) ? userDO.getCountryCode() : "");
        getVO.setPhone(userDO.getPhone());
        getVO.setJobTitle(StringUtils.hasLength(userDO.getJobTitle()) ? userDO.getJobTitle() : "");

        return Wrapper.success(getVO);
    }

    /**
     * 分页查询渠道会员列表
     *
     * @param headers      HttpHeader信息
     * @param pageByNameVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberSalesBindChannelQueryVO>> pageChannels(HttpHeaders headers, MemberManagePageByNameVO pageByNameVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        List<MemberUserChannelDO> userChannels = memberUserChannelRepository.findByMemberIdAndRoleId(loginUser.getMemberId(), loginUser.getMemberRoleId());
        List<Long> relationIds = userChannels.stream().map(MemberUserChannelDO::getMemberRelationId).distinct().collect(Collectors.toList());

        Pageable pageable = PageRequest.of(pageByNameVO.getCurrent() - 1, pageByNameVO.getPageSize(), Sort.by("id").descending());
        Specification<MemberRelationDO> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), MemberStatusEnum.NORMAL.getCode()));
            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_CONSUMER.getCode()));

            //not in 查询
            if (!CollectionUtils.isEmpty(relationIds)) {
                list.add(criteriaBuilder.not(root.get("id").in(relationIds)));
            }

            if (StringUtils.hasLength(pageByNameVO.getName())) {
                Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
                list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + pageByNameVO.getName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<MemberRelationDO> pageList = relationRepository.findAll(specification, pageable);

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(relationDO -> {
            MemberSalesBindChannelQueryVO queryVO = new MemberSalesBindChannelQueryVO();
            queryVO.setRelationId(relationDO.getId());
            queryVO.setMemberId(relationDO.getSubMemberId());
            queryVO.setName(relationDO.getSubMember().getName());
            queryVO.setRoleId(relationDO.getSubRoleId());
            queryVO.setRoleName(relationDO.getSubRole().getRoleName());
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setLevel(relationDO.getLevelRight().getLevel());
            queryVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            queryVO.setCreateTime(relationDO.getCreateTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));
            queryVO.setStatus(relationDO.getStatus());
            queryVO.setStatusName(MemberStatusEnum.getCodeMessage(relationDO.getStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 查询业务员信息、分页查询绑定的渠道列表
     *
     * @param headers HttpHeader信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberSalesChannelQueryVO> getSalesAndPageChannels(HttpHeaders headers, MemberSalesChannelPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberUserDO userDO = memberUserRepository.findById(pageVO.getUserId()).orElse(null);
        if (userDO == null || userDO.getMember() == null || !userDO.getMember().getId().equals(loginUser.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        if (userDO.getIsSales() == null || userDO.getIsSales().equals(EnableDisableStatus.DISABLE.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_IS_NOT_SALES);
        }

        List<MemberOrganizationDO> orgList = new ArrayList<>(userDO.getMember().getOrgs());

        MemberSalesChannelQueryVO queryVO = new MemberSalesChannelQueryVO();
        queryVO.setUserId(userDO.getId());
        queryVO.setName(userDO.getName());
        queryVO.setMemberRoleName(userDO.getRoles().stream().map(MemberRoleDO::getRoleName).collect(Collectors.joining(",")));
        queryVO.setOrgName(MemberOrganizationUtil.joinTitleToString(userDO.getOrg() == null ? 0L : userDO.getOrg().getId(), orgList));
        queryVO.setCountryCode(StringUtils.hasLength(userDO.getCountryCode()) ? userDO.getCountryCode() : "");
        queryVO.setPhone(userDO.getPhone());
        queryVO.setJobTitle(StringUtils.hasLength(userDO.getJobTitle()) ? userDO.getJobTitle() : "");

        List<MemberUserChannelDO> channels = userDO.getUserAuth().getChannels().stream().filter(channel -> channel.getRoleId().equals(loginUser.getMemberRoleId())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(channels)) {
            queryVO.setTotalCount(0L);
            queryVO.setData(new ArrayList<>());
            return Wrapper.success(queryVO);
        }

        List<Long> relationIds = channels.stream().map(MemberUserChannelDO::getMemberRelationId).collect(Collectors.toList());

        Pageable pageable = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("id").descending());
        Specification<MemberRelationDO> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            // in 查询
            Expression<Long> idInExp = root.get("id").as(Long.class);
            list.add(idInExp.in(relationIds));

            if (StringUtils.hasLength(pageVO.getName())) {
                Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
                list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + pageVO.getName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<MemberRelationDO> pageList = relationRepository.findAll(specification, pageable);

        queryVO.setTotalCount(pageList.getTotalElements());
        queryVO.setData(pageList.getContent().stream().map(relationDO -> {
            MemberSalesBindChannelQueryVO channelVO = new MemberSalesBindChannelQueryVO();
            channelVO.setRelationId(relationDO.getId());
            channelVO.setMemberId(relationDO.getSubMemberId());
            channelVO.setName(relationDO.getSubMember().getName());
            channelVO.setRoleId(relationDO.getSubRoleId());
            channelVO.setRoleName(relationDO.getSubRole().getRoleName());
            channelVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            channelVO.setLevel(relationDO.getLevelRight().getLevel());
            channelVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            channelVO.setCreateTime(relationDO.getCreateTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));
            channelVO.setStatus(relationDO.getStatus());
            channelVO.setStatusName(MemberStatusEnum.getCodeMessage(relationDO.getStatus()));
            return channelVO;
        }).collect(Collectors.toList()));

        return Wrapper.success(queryVO);
    }

    /**
     * 业务员绑定渠道列表
     *
     * @param headers       HttpHeader信息
     * @param bindChannelVO 接口参数
     * @return 查询结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> bindSalesChannels(HttpHeaders headers, MemberSalesBindChannelVO bindChannelVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberUserDO userDO = memberUserRepository.findById(bindChannelVO.getUserId()).orElse(null);
        if (userDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        if (userDO.getUserAuth() == null) {
            return Wrapper.fail(ResponseCode.MC_MS_USER_AUTH_DOES_NOT_EXIST);
        }

        //判断渠道与当前会员是否上下级关系
        List<MemberRelationDO> relationDOList = relationRepository.findAllById(bindChannelVO.getRelationIds());
        if (relationDOList.size() != bindChannelVO.getRelationIds().size() || relationDOList.stream().anyMatch(relationDO -> !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.MC_MS_SUB_MEMBER_CHANNEL_DOES_NOT_EXIST);
        }

        QMemberRelationDO qMemberRelationDO = QMemberRelationDO.memberRelationDO;

        //删除已经绑定的渠道
        if (!CollectionUtils.isEmpty(userDO.getUserAuth().getChannels())) {
            List<Long> channelRelationIds = userDO.getUserAuth().getChannels().stream().map(MemberUserChannelDO::getMemberRelationId).collect(Collectors.toList());
            if (NumberUtil.listEqual(channelRelationIds, bindChannelVO.getRelationIds())) {
                return Wrapper.success();
            }

            //删除旧的渠道数据，并将relation表的userId字段置为0
            Set<MemberUserChannelDO> oldChannels = userDO.getUserAuth().getChannels();
            memberUserChannelRepository.deleteAll(oldChannels);
            jpaQueryFactory.update(qMemberRelationDO)
                    .where(qMemberRelationDO.id.in(oldChannels.stream().map(MemberUserChannelDO::getMemberRelationId).collect(Collectors.toList())))
                    .set(qMemberRelationDO.userId, 0L)
                    .execute();
        }

        //添加数据
        List<MemberUserChannelDO> channelList = relationDOList.stream().map(relationDO -> {
            MemberUserChannelDO channelDO = new MemberUserChannelDO();
            channelDO.setCreateTime(LocalDateTime.now());
            channelDO.setMemberId(loginUser.getMemberId());
            channelDO.setRoleId(loginUser.getMemberRoleId());
            channelDO.setUserId(userDO.getId());
            channelDO.setMemberRelationId(relationDO.getId());
            channelDO.setSubMemberId(relationDO.getSubMemberId());
            channelDO.setSubRoleId(relationDO.getSubRoleId());
            return channelDO;
        }).collect(Collectors.toList());
        memberUserChannelRepository.saveAll(channelList);

        //重新存储ChannelAuthBO对象
        userDO.getUserAuth().getChannels().addAll(channelList);
        userDO.getUserAuth().setChannelAuth(userDO.getUserAuth().getChannels().stream().map(channelDO -> {
            ChannelAuthBO channelAuthBO = new ChannelAuthBO();
            channelAuthBO.setRelationId(channelDO.getMemberRelationId());
            channelAuthBO.setMemberId(channelDO.getSubMemberId());
            channelAuthBO.setRoleId(channelDO.getSubRoleId());
            return channelAuthBO;
        }).collect(Collectors.toList()));

        userDO.setIsSales(EnableDisableStatus.ENABLE.getCode());
        memberUserRepository.saveAndFlush(userDO);

        //将当前业务员id覆盖操作员id
        jpaQueryFactory.update(qMemberRelationDO)
                .where(qMemberRelationDO.id.in(bindChannelVO.getRelationIds()))
                .set(qMemberRelationDO.userId, bindChannelVO.getUserId())
                .execute();

        return Wrapper.success();
    }

    /**
     * 解除业务员与渠道的绑定
     *
     * @param headers         HttpHeader信息
     * @param unBindChannelVO 接口参数
     * @return 查询结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> unBindSalesChannel(HttpHeaders headers, MemberSalesUnBindChannelVO unBindChannelVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberUserDO userDO = memberUserRepository.findById(unBindChannelVO.getUserId()).orElse(null);
        if (userDO == null || !userDO.getMember().getId().equals(loginUser.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        MemberUserAuthDO userAuth = userDO.getUserAuth();
        if (userAuth == null) {
            return Wrapper.fail(ResponseCode.MC_MS_USER_AUTH_DOES_NOT_EXIST);
        }

        List<MemberUserChannelDO> channelDOList = memberUserChannelRepository.findByMemberIdAndRoleIdAndUserIdAndMemberRelationIdIn(loginUser.getMemberId(), loginUser.getMemberRoleId(), unBindChannelVO.getUserId(), unBindChannelVO.getRelationIds());
        if (unBindChannelVO.getRelationIds().size() != channelDOList.size()) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_CHANNEL_NOT_EXIST);
        }

        userAuth.getChannels().removeIf(channelDO -> unBindChannelVO.getRelationIds().contains(channelDO.getMemberRelationId()));

        userAuth.setChannelAuth(userAuth.getChannels().stream().map(channelDO -> {
            ChannelAuthBO channelAuthBO = new ChannelAuthBO();
            channelAuthBO.setRelationId(channelDO.getMemberRelationId());
            channelAuthBO.setMemberId(channelDO.getSubMemberId());
            channelAuthBO.setRoleId(channelDO.getSubRoleId());
            return channelAuthBO;
        }).collect(Collectors.toList()));

        memberUserAuthRepository.saveAndFlush(userAuth);
        memberUserChannelRepository.deleteAll(channelDOList);

        List<Long> relIdList = channelDOList.stream().map(MemberUserChannelDO::getMemberRelationId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(relIdList)) {
            //将要删除数据的当前绑定的业务员id置为0
            QMemberRelationDO qMemberRelationDO = QMemberRelationDO.memberRelationDO;
            jpaQueryFactory.update(qMemberRelationDO)
                    .where(qMemberRelationDO.id.in(relIdList))
                    .set(qMemberRelationDO.userId, 0L)
                    .execute();
        }

        return Wrapper.success();
    }

    /**
     * 删除业务员
     *
     * @param headers HttpHeader信息
     * @param idVO    接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> deleteSales(HttpHeaders headers, MemberUserIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberUserDO userDO = memberUserRepository.findById(idVO.getUserId()).orElse(null);
        if (userDO == null || !userDO.getMember().getId().equals(loginUser.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        if (userDO.getIsSales() == null || userDO.getIsSales().equals(EnableDisableStatus.DISABLE.getCode()) || userDO.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_IS_NOT_SALES);
        }

        MemberUserAuthDO userAuth = userDO.getUserAuth();
        if (userAuth == null) {
            return Wrapper.fail(ResponseCode.MC_MS_USER_AUTH_DOES_NOT_EXIST);
        }

        if (!CollectionUtils.isEmpty(userAuth.getChannels())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_SALES_CHANNEL_IS_NOT_EMPTY);
        }

        userDO.setIsSales(EnableDisableStatus.DISABLE.getCode());
        memberUserRepository.saveAndFlush(userDO);

        return Wrapper.success();
    }

    /**
     * 返回组织机构
     *
     * @param headers 头部信息
     * @return 组织机构列表
     */
    @Override
    public Wrapper<List<String>> getMemberOrganizationList(HttpHeaders headers) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberDO memberDO = memberRepository.findById(loginUser.getMemberId()).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }
        List<MemberOrganizationDO> orgList = new ArrayList<>(memberDO.getOrgs());
        return Wrapper.success(orgList.stream().map(MemberOrganizationDO::getTitle).collect(Collectors.toList()));
    }
}
